今天開始的幾天,要來跟大家分享verilog語法,分享語法的過程中會用一些圖解的方式呈現,也就是說用把一些語法轉換成邏輯電路,好讓大家在寫的同時能知道自己寫的程式會產生什麼樣電路,那就讓我們開始吧.
以下是做幾個邏輯運算的小電路:
module test(clk,reset,a,b,c);
input clk; //時脈訊號
input reset; //訊號重置
input a; //輸入訊號
input b; //輸入訊號
output c;//輸出訊號
wire tamp1; //宣告為wire訊號
wire tamp2; //宣告為wire訊號
reg tamp3; //宣告為reg訊號
assign tamp1 = a & b; //兩個輸入訊號做and
assign tamp2 = a | b; //兩個輸入訊號做or
assign c = tamp3;
always@(posedge clk)begin //clock正緣觸發
if(reset)
tamp3 <= 0; //reset等於1時做初始化
else
tamp3 <= ~(tamp1 ^ tamp2); //兩條訊號線做xnor
end
endmodule
依上圖可以看到一個簡單的電路需要具備哪些元素,那這邊就對這一個小電路做個別的解釋.
module:verilog起始宣告的關鍵字,接著後面的括弧裡面放input,output的腳位,最後面要搭配一個endmodule,可以把數個module寫在同一個.v檔案裡面,但通常還是會拆開來寫在不同的.v檔裡面較方便管理.
input output:輸入輸出腳位,可以和module裡面的訊號線合併,以上圖為例也可以寫成:
module test(
input clk,
input reset,
input a,
input b,
output c
);
module的input宣告方式必須是wire的形式,以上面這樣寫的預設值就是wire,所以不用特別去修改,output的話可以是wire 或者是reg,所以說如果你的output想要宣告為reg的話,以上面的例子可以寫成:
output reg c
這邊提醒大家一下,output訊號線是不可缺的成員之一,一個電路如果沒有輸出訊號線,等於說是沒有用的電路,在模擬階段可能看不出來,但實際在跑合成時如果沒有輸出訊號的話,整個電路可能都會被優化掉.
宣告自己會用到的訊號線,宣告wire形式的話為幫你做拉線的動作,宣告
成reg的話則會用暫存器幫你儲存起來,這邊說明一下宣告的方式
reg[7:0] A => 宣告一個名字為A的8bits的暫存器.
reg[7:0] A [7:0] =>宣告8個8 bits名字為A的暫存器,使用方法就像是軟體陣列的形式.
宣告成reg A[15:0]跟宣告成reg B[0:15]雖然都是16bits的暫存器,但儲存的方式就會不一樣了,使用上要小心,wire形式也能宣告像是array的形式,方法同reg.
assign:要求指定的訊號線要做什麼運算,例如:
assign “tamp1 = a & b;”把a and b 的結果指定給 tamp1,這邊要注意的是指定的對象必須宣告為wire的形式.
always:跟assign意思差不多,但他可以在always裡面做比較多指定的運算
那裡面宣告的形式必須為reg的形式,always的使用方式會在下次做更詳細的介紹.
下圖是這次教學所產生的電路圖,大家可以參考一下.
還蠻鼓勵大家一開始在寫的時候能想像一下,我這樣寫會產生什麼樣的電路,會用什麼樣的邏輯閘去產生,線又會怎麼接,這樣去培養寫電路感覺,自然而然就不會覺得寫verilog很乏味了,那今天就先到這裡喔.